<template>
  <div class="picker-main">
    <button @click="showPicker()">选择器</button>
    <span>{{city}}</span>
    <div v-if="show" class="picker">
      <section class="picker-main">
        <h3>
          <span @click="show = false">取消</span>
          <span>请选择</span>
          <span @click="sure()">确认</span>
        </h3>
        <ul ref="ul">
          <li
            v-for="(item, index) in list"
            :key="index"
            :class="active==item.id?'active':active==item.id-1||active==item.id+1?'active2':null"
            :ref="'li'+item.label"
          >{{item.val}}</li>
        </ul>
      </section>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      list: [
        { id: -9, city: '', label: '' },
        { id: -9, city: '', label: '' },
        {
          id: 0,
          val: '北京',
          label: 'bj'
        },
        {
          id: 1,
          val: '上海',
          label: 'sh'
        },
        {
          id: 2,
          val: '广州',
          label: 'gz'
        },
        {
          id: 3,
          val: '深圳',
          label: 'sz'
        },
        {
          id: 4,
          val: '北海',
          label: 'bh'
        },
        { id: -9, city: '', label: '' },
        { id: -9, city: '', label: '' }
      ],
      show: false,
      active: 0,
      city: '',
      listOffsetTop: [],
      timer: null
    }
  },
  methods: {
    showPicker() {
      this.show = true
      this.active = 0
      this.timer = setTimeout(() => {
        clearTimeout(this.timer)
        this.getOffsetTop()
        this.computeActive()
      }, 50)
    },
    sure() {
      this.list.map((item, index) => {
        item.id == this.active ? (this.city = item.val) : null
      })
      this.show = false
    },
    getOffsetTop() {
      this.listOffsetTop = []
      this.list.map((item, index) => {
        let liTop = this.$refs['' + item.label]
        this.listOffsetTop.push(liTop[0].offsetTop - 41)
      })
    },
    computeActive() {
      let scroll = this.$refs.ul
      scroll.addEventListener('scroll', () => {
        this.listOffsetTop.map((item, index) => {
          item <= scroll.scrollTop + 100 ? (this.active = index - 2) : null
        })
      })
    }
  }
};
</script>
<style lang="less" scoped>
.picker {
  background-color: rgba(0, 0, 0, 0.2);
  max-height: 100vh;
  width: 100%;
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  display: flex;
  .picker-main {
    width: 100%;
    position: absolute;
    bottom: 0;
    background-color: #fff;
    h3 {
      padding: 0;
      margin: 0;
      display: flex;
      justify-content: space-around;
      border-bottom: solid 1px #ddd;
      font-size: 20px;
      line-height: 40px;
    }
    ul {
      max-height: 250px;
      padding: 0;
      margin: 0;
      overflow: auto;
      background-color: #fff;
      li {
        list-style: none;
        font-size: 25px;
        line-height: 50px;
        text-align: center;
        opacity: 0.3;
        height: 50px;
        background-color: #fff;
      }
    }
  }
}
.active {
  background-color: #ddd !important;
  color: #333;
  opacity: 1 !important;
}
.active2 {
  color: #333;
  opacity: 0.6 !important;
}
</style>
